using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;

public class calculator : MonoBehaviour
{
    private string BoxText;
    private string tmpText;
    private int length;
    Stack<string> num_stack;
    Stack<string> op_stack;

    void init()
    {
        BoxText = "";
        tmpText = "";
        num_stack = new Stack<string>();
        op_stack = new Stack<string>();
    }

    // Start is called before the first frame update
    void Start()
    {
        init();
    }

    void OnGUI()
    {
        // 创建计算器UI界面
        GUIStyle buttonstyle = new GUIStyle(GUI.skin.button);
        buttonstyle.fontSize = 24;

        GUI.Box(new Rect(100, 10, 390, 550), "");
        GUI.Box(new Rect(120, 50, 350, 90), tmpText + "\n" + BoxText, buttonstyle);

        length = tmpText.Length; // 字符串长度

        if(GUI.Button(new Rect(120, 170, 140, 70), "Reset", buttonstyle)) {
            init();
        }
        if(GUI.Button(new Rect(260, 170, 70, 70), "+", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '²' || tmpText[length - 1] == '½')) {
                tmpText += "+";
                while (op_stack.Count != 0 && (op_stack.Peek() == "x" || op_stack.Peek() == "÷")) {
                    calculate_mul_div();
                }
                op_stack.Push("+");
            }
        }
        if(GUI.Button(new Rect(330, 170, 70, 70), "-", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '²' || tmpText[length - 1] == '½')) {
                tmpText += "-";
                while (op_stack.Count != 0 && (op_stack.Peek() == "x" || op_stack.Peek() == "÷")) {
                    calculate_mul_div();
                }
                op_stack.Push("-");
            }
        }
        if(GUI.Button(new Rect(400, 170, 70, 70), "x²", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '½'))
            {
                tmpText += "²";
                string str = num_stack.Pop();
                if (str.Contains('.'))
                {
                    double tmp = double.Parse(str);
                    double res = tmp * tmp;
                    num_stack.Push(res.ToString());
                }
                else
                {
                    int tmp = int.Parse(str);
                    int res = tmp * tmp;
                    num_stack.Push(res.ToString());
                }
            }
        }
        if (GUI.Button(new Rect(120, 240, 70, 70), "1", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "1";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("1");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '1';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(190, 240, 70, 70), "2", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "2";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("2");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '2';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(260, 240, 70, 70), "3", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "3";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("3");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '3';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(330, 240, 70, 70), "x", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '²' || tmpText[length - 1] == '½' || tmpText[length - 1] == '%')) {
                tmpText += "x";
                op_stack.Push("x");
            }
        }
        if(GUI.Button(new Rect(400, 240, 70, 70), "←", buttonstyle)) {
            if (length > 0 && (tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')) {
                double num = double.Parse(num_stack.Pop());
                num /= 10;
                string str;
                int pos = 0;
                if (op_stack.Count != 0)
                {
                    for (int i = length - 1; i >= 0; i--)
                    {
                        if (tmpText[i] == '+' || tmpText[i] == '-' || tmpText[i] == 'x' || tmpText[i] == '÷')
                        {
                            pos = i;
                            break;
                        }
                    }
                    str = tmpText.Substring(0, pos + 1);
                }
                else str = "";
                tmpText = str + num.ToString();
                num_stack.Push(num.ToString());
            }
        }
        if(GUI.Button(new Rect(120, 310, 70, 70), "4", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "4";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("4");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '4';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(190, 310, 70, 70), "5", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "5";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("5");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '5';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(260, 310, 70, 70), "6", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "6";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("6");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '6';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(330, 310, 70, 70), "÷", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '²' || tmpText[length - 1] == '½' || tmpText[length - 1] == '%')) {
                tmpText += "÷";
                op_stack.Push("÷");
            }
        }
        if(GUI.Button(new Rect(400, 310, 70, 70), "√", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '²')) {
                tmpText += "½"; 
                string str = num_stack.Pop();
                if (str.Contains('.'))
                {
                    double tmp = double.Parse(str);
                    double res = Math.Sqrt(tmp);
                    num_stack.Push(res.ToString());
                }
                else
                {
                    int tmp = int.Parse(str);
                    double res = Math.Sqrt(tmp);
                    num_stack.Push(res.ToString());
                }
            }
        }
        if(GUI.Button(new Rect(120, 380, 70, 70), "7", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "7";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("7");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '7';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(190, 380, 70, 70), "8", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "8";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("8");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '8';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(260, 380, 70, 70), "9", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                tmpText += "9";
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("9");
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    string str = num_stack.Pop() + '9';
                    num_stack.Push(str);
                }
            }
        }
        if(GUI.Button(new Rect(330, 380, 140, 70), "%", buttonstyle)) {
            if (length > 0 && (tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')) {
                tmpText += "%";
                double num = double.Parse(num_stack.Pop());
                num /= 100;
                num_stack.Push(num.ToString());
            }
        }
        if(GUI.Button(new Rect(120, 450, 140, 70), "0", buttonstyle)) {
            if (length == 0 || (length > 0 && tmpText[length - 1] != '=' && tmpText[length - 1] != '%'))
            {
                if (num_stack.Count == op_stack.Count)
                {
                    num_stack.Push("0");
                    tmpText += "0";
                }
                else if (num_stack.Count - op_stack.Count == 1)
                {
                    if (num_stack.Peek() != "0")
                    {
                        string str = num_stack.Pop() + '0';
                        num_stack.Push(str);
                        tmpText += "0";
                    }
                }
            }
        }
        if(GUI.Button(new Rect(260, 450, 70, 70), ".", buttonstyle)) {
            if (length > 0 && (tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                && !num_stack.Peek().Contains('.')) {
                tmpText += ".";
                string str = num_stack.Pop() + ".";
                num_stack.Push(str);
            }
        }
        if(GUI.Button(new Rect(330, 450, 140, 70), "=", buttonstyle)) {
            if (length > 0 && ((tmpText[length - 1] >= '0' && tmpText[length - 1] <= '9')
                || tmpText[length - 1] == '²' || tmpText[length - 1] == '½' || tmpText[length - 1] == '%'))
            {
                tmpText += "=";
                while (op_stack.Count != 0)
                {
                    if (op_stack.Peek() == "+" || op_stack.Peek() == "-")
                        calculate_plus_str();
                    else calculate_mul_div();
                }
                BoxText = num_stack.Peek().ToString();
            }
        }

    }
    void calculate_mul_div(){
        double num1 = double.Parse(num_stack.Pop());
        double num2 = double.Parse(num_stack.Pop());
        double res;
        if (op_stack.Peek() == "x") {
            res = num1 * num2;
        }
        else {
            res = num2 / num1;
        }
        num_stack.Push(res.ToString());
        op_stack.Pop();
    }
    void calculate_plus_str(){
        double num1 = double.Parse(num_stack.Pop());
        double num2 = double.Parse(num_stack.Pop());
        double res;
        if (op_stack.Peek() == "+") {
            res = num1 + num2;
        }
        else {
            res = num2 - num1;
        }
        num_stack.Push(res.ToString());
        op_stack.Pop();
    }
}
